﻿using System;
using System.Web;
using System.Collections;

namespace Caramel.Web
{
	public class RequestLocalStorage : ILocalStorage
	{
		private static readonly object Key = new object();

		public object this[object key]
		{
			get
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				return hashtable[key];
			}
			set
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				hashtable[key] = value;
			}
		}

		public void Clear()
		{
			var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

			if (hashtable != null)
			{
				hashtable.Clear();
			}
		}

		public void Add(object key, object value)
		{
			var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

			if (hashtable == null)
			{
				hashtable = new Hashtable();
				HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
			}

			hashtable.Add(key, value);
		}

		public bool Contains(object key)
		{
			var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

			if (hashtable == null)
			{
				hashtable = new Hashtable();
				HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
			}

			return hashtable.Contains(key);
		}

		public IDictionaryEnumerator GetEnumerator()
		{
			var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

			if (hashtable == null)
			{
				hashtable = new Hashtable();
				HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
			}

			return hashtable.GetEnumerator();
		}

		public bool IsFixedSize
		{
			get
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				return hashtable.IsFixedSize;
			}
		}

		public bool IsReadOnly
		{
			get
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				return hashtable.IsReadOnly;
			}
		}

		public ICollection Keys
		{
			get
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				return hashtable.Keys;
			}
		}

		public void Remove(object key)
		{
			var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

			if (hashtable == null)
			{
				hashtable = new Hashtable();
				HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
			}

			hashtable.Remove(key);
		}

		public ICollection Values
		{
			get
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				return hashtable.Values;
			}
		}

		public void CopyTo(Array array, int index)
		{
			var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

			if (hashtable == null)
			{
				hashtable = new Hashtable();
				HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
			}

			hashtable.CopyTo(array, index);
		}

		public int Count
		{
			get
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				return hashtable.Count;
			}
		}

		public bool IsSynchronized
		{
			get
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				return hashtable.IsSynchronized;
			}
		}

		public object SyncRoot
		{
			get
			{
				var hashtable = HttpContext.Current.Items[RequestLocalStorage.Key] as Hashtable;

				if (hashtable == null)
				{
					hashtable = new Hashtable();
					HttpContext.Current.Items[RequestLocalStorage.Key] = hashtable;
				}

				return hashtable.SyncRoot;
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.GetEnumerator();
		}
	}
}
